﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Web.UI.WebControls;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using ServBus.ListForm2010.Common.XSNOperator;
using ServBus.ListForm2010.License;
using ServBus.ListForm2010.Resources;
using ServBus.ListForm2010.Utility;

namespace ServBus.ListForm2010.Layouts.ListForm2010
{
    public partial class ListFormManagement : LayoutsPageBase
    {
        private string _contentTypeName;
        private License.License _license;
        private string _errorMsg = "";
        private static readonly DllResource Resource = new DllResource("ServBus.ListForm2010.Common.Resources|AppPages");

        private void ErrorLog(Exception ex, bool internalError)
        {
            if (internalError)
            {
                errorPanel.Visible = true;
            }
            else
            {
                LTException.Text = ex.Message;
                LTException.Visible = true;
            }
            Utility.ErrorLog.Write("ListFormManagement" + "\r\n" + Request.Url + "\r\n" + ex.Message + "\r\n" + ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
        }

        private bool IsProLicense()
        {
            _license = LicenseContainer.ProductLicense;
            if (_license.FeatureSet == FeatureSet.Professional)
            {
                return true;
            }
            return false;
        }

        #region Page

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!Page.IsPostBack)
                {
                    titleLabel.Text = Resource.GetString("PageTitle_ListFormSettings");
                    Activations activations = new Activations(SPContext.Current.Site.WebApplication);
                    if (!activations.IsActivationValid(SPContext.Current.Web, out _errorMsg))
                    {
                        ErrorLog(new Exception(_errorMsg), false);
                    }
                    else
                    {
                        InitialData();
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorLog(ex, true);
            }
        }

        private void InitialData()
        {
            ctDdl.Visible = false;
            okButton.Visible = false;
            cancelButton.Visible = false;
            if (!string.IsNullOrEmpty(Request["source"]))
            {
                Activations activations = new Activations(SPContext.Current.Site.WebApplication);
                if (!activations.IsActivationValid(SPContext.Current.Web, out _errorMsg))
                {

                    ErrorLog(new Exception(_errorMsg), false);
                }
                else
                {
                    ctDdlLabel.Text = Resource.GetString("ListBus_Settings_ctSelect");
                    ctDdlLabel.Visible = true;

                    okButton.Text = Resource.GetString("ListBus_Settings_BtnOK");
                    okButton.Enabled = false;
                    okButton.Visible = true;
                    cancelButton.Visible = true;

                    cancelButton.Text = Resource.GetString("ListBus_Settings_BtnCancel");
                    ctDdl.Items.Clear();

                    displayFormLabel.Text = Resource.GetString("FormView_display");
                    dispalyFormReadOnlyLabel.Text = Resource.GetString("FormView_display_readOnly");
                    editFormLabel.Text = Resource.GetString("FormView_edit");
                    newFormLabel.Text = Resource.GetString("FormView_new");

                    Guid siteId = SPContext.Current.Site.ID;
                    Guid webId = SPContext.Current.Web.ID;

                    Guid listId = new Guid(Request["source"]);

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                SPList list = web.Lists[listId];

                                //Folder SPContentTypeId is 0x0120
                                SPContentType folderCType = site.RootWeb.ContentTypes[new SPContentTypeId("0x0120")];

                                for (int i = 0; i < list.ContentTypes.Count; i++)
                                {
                                    SPContentType cType = list.ContentTypes[i];
                                    if (folderCType != null && !cType.Id.IsChildOf(folderCType.Id))
                                    {
                                        ctDdl.Items.Add(cType.Name);
                                        if (ctDdl.Items.Count == 1) CtChanged(cType.Name);
                                    }
                                }
                            }
                        }
                    });
                    ctDdl.Visible = true;
                }
            }
        }

        protected void CtDdlChanged(object sender, EventArgs e)
        {
            try
            {
                _contentTypeName = ctDdl.SelectedItem.Text;
                CtChanged(_contentTypeName);
            }
            catch (Exception ex)
            {
                ErrorLog(ex, true);
            }
        }

        protected void CreateFormRdChanged(object sender, EventArgs e)
        {
            okButton.Enabled = true;
        }

        protected void ModifyFormRdChanged(object sender, EventArgs e)
        {
            if (ModifyFormRd.Checked)
            {
                SpecificViewRd.Checked = false;
                dispViewDdl.Enabled = false;
                editViewDdl.Enabled = false;
                newViewDdl.Enabled = false;
                dispalyFormReadOnlyCb.Enabled = false;

                DefaultFormRd.Checked = false;
                deleteCB.Checked = false;
                deleteCB.Enabled = false;
                if (IsProLicense())
                {
                    EditLookupStructure.Enabled = true;
                }
            }
            okButton.Enabled = true;

        }

        protected void SpecificViewRdChanged(object sender, EventArgs e)
        {
            if (SpecificViewRd.Checked)
            {
                ModifyFormRd.Checked = false;
                if (IsProLicense())
                {
                    EditLookupStructure.Checked = false;
                    EditLookupStructure.Enabled = false;
                }
                DefaultFormRd.Checked = false;
                deleteCB.Checked = false;
                deleteCB.Enabled = false;

                dispViewDdl.Enabled = true;
                editViewDdl.Enabled = true;
                newViewDdl.Enabled = true;
                dispalyFormReadOnlyCb.Enabled = true;
            }
            okButton.Enabled = true;

        }

        protected void DefaultFormRdChanged(object sender, EventArgs e)
        {
            if (DefaultFormRd.Checked)
            {
                SpecificViewRd.Checked = false;
                dispViewDdl.Enabled = false;
                editViewDdl.Enabled = false;
                newViewDdl.Enabled = false;
                dispalyFormReadOnlyCb.Enabled = false;

                ModifyFormRd.Checked = false;
                if (IsProLicense())
                {
                    EditLookupStructure.Checked = false;
                    EditLookupStructure.Enabled = false;
                }
                deleteCB.Enabled = true;
            }
            okButton.Enabled = true;
        }

        protected void OkButtonClick(object sender, EventArgs e)
        {
            try
            {
                if (CreateFormRd.Visible)
                {
                    if (CreateFormRd.SelectedValue == "1")
                    {
                        CustomizeForm();
                    }
                    else if (CreateFormRd.SelectedValue == "2")
                    {
                        CreateLookupForm();
                    }
                }
                else
                {

                    if (ModifyFormRd.Checked)
                    {
                        if (IsProLicense() && EditLookupStructure.Checked)
                        {
                            CreateLookupForm();
                        }
                        else
                        {
                            ModifyExistingForm();
                        }
                    }
                    else if (SpecificViewRd.Checked)
                    {
                        UpdateViewConfigItem();
                    }
                    else if (DefaultFormRd.Checked)
                    {
                        DefaultForm();
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorLog(ex, true);
            }
        }

        protected void CancelButtonClick(object sender, EventArgs e)
        {
            Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('ok');</script>");
        }

        private void CtChanged(string ctName)
        {
            try
            {
                if (string.IsNullOrEmpty(ctName)) return;
                okButton.Enabled = false;
                Guid siteId = SPContext.Current.Site.ID;
                Guid webId = SPContext.Current.Web.ID;
                Guid listId = new Guid(Request["source"]);

                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (SPSite site = new SPSite(siteId))
                    {
                        using (SPWeb web = site.OpenWeb(webId))
                        {
                            web.AllowUnsafeUpdates = true;
                            SPList list = web.Lists[listId];
                            SPContentType cType = list.ContentTypes[ctName];
                            SPFile xsnFile = null;
                            if (!IsCustomizeFormExist(web, cType, ref xsnFile))
                            {
                                modifyPanel.Visible = false;
                                CreateFormRd.Items.Clear();
                                ListItem item1 = new ListItem(Resource.GetString("ListBus_Settings_Customize"), "1");

                                CreateFormRd.Items.Add(item1);
                                if (IsProLicense())
                                {
                                    ListItem item2 = new ListItem(Resource.GetString("ListBus_Settings_LookupForm_Create"), "2");
                                    CreateFormRd.Items.Add(item2);
                                }
                                CreateFormRd.Visible = true;
                                //CustomizeFormRd.Text = Resource.GetString("ListBus_Settings_Customize");
                                //CustomizeFormRd.Visible = true;
                                //CreateLookupFormRd.Text = Resource.GetString("ListBus_Settings_LookupForm_Create");
                                //CreateLookupFormRd.Visible = true;
                            }
                            else
                            {
                                CreateFormRd.Visible = false;


                                ModifyFormRd.Text = Resource.GetString("ListBus_Settings_Modify");
                                ModifyFormRd.Checked = false;
                                if (IsProLicense())
                                {
                                    EditLookupStructure.Text = Resource.GetString("ListBus_Settings_LookupForm_Modify");
                                    EditLookupStructure.Checked = false;
                                    EditLookupStructure.Enabled = false;
                                }
                                else
                                {
                                    EditLookupStructure.Enabled = false;
                                    EditLookupStructure.Visible = false;
                                }
                                SpecificViewRd.Text = Resource.GetString("ListBus_Settings_SpecificViews");
                                SpecificViewRd.Checked = false;
                                DefaultFormRd.Text = Resource.GetString("ListBus_Settings_Default");
                                DefaultFormRd.Checked = false;
                                deleteCB.Text = Resource.GetString("ListBus_Settings_Delete");
                                deleteCB.Checked = false;
                                deleteCB.Enabled = false;

                                dispalyFormReadOnlyCb.Checked = true;
                                dispalyFormReadOnlyCb.Enabled = false;
                                dispViewDdl.Enabled = false;
                                editViewDdl.Enabled = false;
                                newViewDdl.Enabled = false;

                                dispViewDdl.Items.Clear();
                                editViewDdl.Items.Clear();
                                newViewDdl.Items.Clear();
                                string defalutView = "";
                                IEnumerable<string> views = getViews(xsnFile, ref defalutView);
                                Dictionary<string, string> configViews = GetViewConfigItem(web, Convert.ToString(listId), Convert.ToString(cType.Id));
                                bool configViewsExists = configViews.Count > 0;
                                foreach (string formView in views)
                                {
                                    //string formViewId = formView.Substring(0, formView.IndexOf('_'));
                                    string formViewName = formView.Substring(formView.IndexOf('_') + 1);
                                    ListItem listItem1 = new ListItem(formViewName, formViewName);
                                    ListItem listItem2 = new ListItem(formViewName, formViewName);
                                    ListItem listItem3 = new ListItem(formViewName, formViewName);
                                    dispViewDdl.Items.Add(listItem1);
                                    editViewDdl.Items.Add(listItem2);
                                    newViewDdl.Items.Add(listItem3);
                                }

                                if (configViewsExists)
                                {
                                    dispViewDdl.Items.FindByValue(configViews["DISP"]).Selected = true;
                                    editViewDdl.Items.FindByValue(configViews["EDIT"]).Selected = true;
                                    newViewDdl.Items.FindByValue(configViews["NEW"]).Selected = true;
                                    if (configViews["DISP_ReadOnly"].Equals("0")) dispalyFormReadOnlyCb.Checked = false;
                                }
                                else
                                {
                                    dispViewDdl.Items.FindByValue(defalutView).Selected = true;
                                    editViewDdl.Items.FindByValue(defalutView).Selected = true;
                                    newViewDdl.Items.FindByValue(defalutView).Selected = true;
                                }

                                modifyPanel.Visible = true;

                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                ErrorLog(ex, true);
            }
        }

        private IEnumerable<string> getViews(SPFile file, ref string defautview)
        {
            if (defautview == null) throw new ArgumentNullException("defautview");

            byte[] xsnContent = file.OpenBinary();
            XmlDocument xsfDoc = new XmlDocument();
            XsnExtractor extractor = new XsnExtractor(xsnContent);
            byte[] xsfContent = extractor.Extract("manifest.xsf");
            using (MemoryStream xsfStream = new MemoryStream(xsfContent))
            {
                xsfDoc.Load(xsfStream);
            }

            // Validate Feature
            FeatureChecker checker = new FeatureChecker(xsfDoc);
            List<string> views = checker.ViewInfo;
            defautview = checker.DefaultView;
            return views;
        }

        #endregion

        #region Form Action

        private void ModifyExistingForm()
        {
            try
            {
                string xsnLocation = "";
                _contentTypeName = ctDdl.SelectedItem.Text;
                if (!string.IsNullOrEmpty(_contentTypeName))
                {

                    Guid siteId = SPContext.Current.Site.ID;
                    Guid webId = SPContext.Current.Web.ID;
                    Guid listId = new Guid(Request["source"]);
                    string siteUrl = SPContext.Current.Site.Url;

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                web.AllowUnsafeUpdates = true;
                                SPList list = web.Lists[listId];
                                SPContentType cType = list.ContentTypes[_contentTypeName];
                                xsnLocation = siteUrl + cType.ResourceFolder.ServerRelativeUrl + "/template.xsn";

                                //ExtractXSD()
                                ExtractXSD(web, cType);
                                //UpdateXSD()
                                UpdateXSD(web, cType);
                            }
                        }
                    });
                }
                //Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('Operation Successful!')</script>");
                if (!string.IsNullOrEmpty(xsnLocation))
                {
                    Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate('" + xsnLocation + "'); }window.frameElement.commitPopup('ok');</script>");
                    //Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate ('" + xsnLocation + "'); }</script>");
                }
            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        #region UpdateXSD
        private void UpdateXSD(SPWeb web, SPContentType cType)
        {
            Guid siteId = SPContext.Current.Site.ID;
            Guid webId = SPContext.Current.Web.ID;

            #region Generate XSN

            //Create Main ListInfo
            //Main List
            XListInfo mListInfo = new XListInfo();
            mListInfo.GenerateListInfo(cType.ParentList);
            mListInfo.AddContentTypeInfo(cType);

            ArrayList sListArrayList = getConfigItem(web, cType.ParentList.ID.ToString(), cType.Id.ToString());
            List<XListInfo> sListInfos = new List<XListInfo>();
            if (sListArrayList.Count > 0)
            {
                foreach (string sListDef in sListArrayList)
                {
                    string sListId = sListDef.Split(';')[0];
                    string sContentTypeId = sListDef.Split(';')[1];
                    XListInfo sListInfo = new XListInfo();
                    SPList sList = web.Lists[new Guid(sListId)];
                    SPContentType sCType = sList.ContentTypes[new SPContentTypeId(sContentTypeId)];
                    sListInfo.GenerateListInfo(sList);
                    sListInfo.AddContentTypeInfo(sCType);
                    sListInfos.Add(sListInfo);
                }
            }

            XSNOperator xsnOperator = new XSNOperator
            {
                SiteId = siteId,
                WebId = webId,
                ListId = cType.ParentList.ID,
                CTypeId = cType.Id,
                XSNTemplateFolder = Server.MapPath("/_layouts/ListForm2010/xsn_template/"),
                G_Site_Url = SPContext.Current.Site.Url,
                G_XSN_Url =
                    SPContext.Current.Site.Url + cType.ParentList.RootFolder.ServerRelativeUrl + "/" +
                    cType.ResourceFolder.Name + "/template.xsn",
                MListInfo = mListInfo,
                SListsInfo = sListInfos
            };

            string xsdTemp = @"C:\TempXsnFiles\" + cType.Id.ToString();
            xsnOperator.RefresehXSN(xsdTemp);
            UploadFileToFormLib(xsnOperator);

            #endregion
        }

        private ArrayList getConfigItem(SPWeb web, string mListID, string mContentTypeID)
        {
            ArrayList sListInfo = new ArrayList();
            if (!string.IsNullOrEmpty(mListID) && !string.IsNullOrEmpty(mContentTypeID))
            {
                try
                {
                    SPList configList = web.Lists[Constants.LookupForm_Config_NAME];
                    SPQuery query = new SPQuery
                    {
                        Query =
                            "<Where><And><Eq><FieldRef Name='Title' /><Value Type='Text'>" + mListID +
                            "</Value></Eq><Eq><FieldRef Name='mContentType' /><Value Type='Text'>" + mContentTypeID +
                            "</Value></Eq></And></Where>"
                    };
                    SPListItemCollection items = configList.GetItems(query);
                    if (items.Count > 0)
                    {
                        string sListValue = Convert.ToString(items[0]["sTitle"]);
                        string sContentTypeValue = Convert.ToString(items[0]["sContentType"]);

                        if (!string.IsNullOrEmpty(sListValue) && !string.IsNullOrEmpty(sContentTypeValue))
                        {
                            if (sListValue.Contains(";"))
                            {
                                string[] sLists = sListValue.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                string[] sCTs = sContentTypeValue.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                for (int i = 0; i < sLists.Length; i++)
                                {
                                    sListInfo.Add(sLists[i] + ";" + sCTs[i]);
                                }
                            }
                            else
                            {
                                sListInfo.Add(sListValue + ";" + sContentTypeValue);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return sListInfo;
        }

        private Dictionary<string, string> ExtractXSD(SPWeb Web, SPContentType cType)
        {
            Dictionary<string, string> _targetXSDFiles = new Dictionary<string, string>();
            //Get ContentType
            string xsdURL = cType.ParentList.RootFolder.ServerRelativeUrl + "/" + cType.ResourceFolder.Name + "/template.xsn";
            string xsdTemp = @"C:\TempXsnFiles\" + cType.Id.ToString();
            SPFile m_file = Web.GetFile(xsdURL);
            if (m_file.Exists)
            {
                //Get XSN File Temp Location
                _targetXSDFiles.Add(xsdURL, xsdTemp);
                //Move XSD To Temp Location
                int size = 10 * 1024;
                using (Stream stream = m_file.OpenBinaryStream())
                {
                    Directory.CreateDirectory(xsdTemp);
                    string xsdTempLoaction = xsdTemp + "\\template.xsn";
                    using (FileStream fs = new FileStream(xsdTempLoaction, FileMode.Create, FileAccess.Write))
                    {
                        byte[] xsd_content = m_file.OpenBinary();
                        int nBytesRead = 0;
                        while ((nBytesRead = stream.Read(xsd_content, 0, xsd_content.Length)) > 0)
                        {
                            fs.Write(xsd_content, 0, nBytesRead);
                        }
                    }
                }
            }

            foreach (string xsdURL1 in _targetXSDFiles.Keys)
            {
                //Unpack XSN to local
                string xsdTemp1 = _targetXSDFiles[xsdURL];
                string xsdTempLoaction = _targetXSDFiles[xsdURL] + "\\template.xsn";
                string cmdString = string.Format("expand \"{0}\" \"{1}\" -f:*", xsdTempLoaction, xsdTemp);
                string cmdResult = RunCommand(cmdString, _targetXSDFiles[xsdURL]);
            }

            return _targetXSDFiles;
            //Replace xsd file
            //Package and Upload
        }

        private string RunCommand(string cmdString, string xsdDictory)
        {
            Process p = new Process();
            //启动DOS程序
            p.StartInfo.WorkingDirectory = xsdDictory;
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;//不用Shell启动
            p.StartInfo.RedirectStandardInput = true;//重定向输入
            p.StartInfo.RedirectStandardOutput = true;//重定向输出
            p.StartInfo.CreateNoWindow = true;//不显示窗口
            p.Start();//开始进程
            p.StandardInput.WriteLine(cmdString);// 向cmd.exe输入command
            p.StandardInput.WriteLine("exit");//结束
            p.WaitForExit(60000);//等等执行完成
            string outPutString = p.StandardOutput.ReadToEnd();// 得到cmd.exe的输出
            p.Close();
            return outPutString;
        }
        #endregion

        private void CustomizeForm()
        {
            try
            {
                string xsnLocation = "";
                string destFolderUrl;
                _contentTypeName = ctDdl.SelectedItem.Text;
                string curWebUrl = SPContext.Current.Web.Url;
                string curXSNLocation = string.Empty;

                if (!string.IsNullOrEmpty(_contentTypeName))
                {

                    Guid siteId = SPContext.Current.Site.ID;
                    Guid webId = SPContext.Current.Web.ID;
                    Guid listId = new Guid(Request["source"]);

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                web.AllowUnsafeUpdates = true;
                                SPList list = web.Lists[listId];
                                SPContentType cType = list.ContentTypes[_contentTypeName];
                                xsnLocation = web.Url + "/" + cType.ResourceFolder.Url + "/template.xsn";
                                //for alternative mapping
                                curXSNLocation = curWebUrl + "/" + cType.ResourceFolder.Url + "/template.xsn";

                                if (!web.GetFile(xsnLocation).Exists)
                                {
                                    //display_lb.aspx, edit_lb.aspx, new_lb.aspx
                                    destFolderUrl = cType.ResourceFolder.ServerRelativeUrl;
                                    string listParameter = "listId=" + list.ID.ToString();
                                    string cTypeParameter = "ctypeId=" + cType.Id.ToString();
                                    string uploadFileName = Microsoft.SharePoint.Utilities.SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\ListForm2010\Template.aspx");
                                    FileStream fileStream = File.Open(uploadFileName, FileMode.Open);
                                    web.Files.Add(destFolderUrl + "/display_lb.aspx", fileStream, true);
                                    cType.DisplayFormUrl = destFolderUrl + "/display_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                    web.Files.Add(destFolderUrl + "/edit_lb.aspx", fileStream, true);
                                    cType.EditFormUrl = destFolderUrl + "/edit_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                    web.Files.Add(destFolderUrl + "/new_lb.aspx", fileStream, true);
                                    cType.NewFormUrl = destFolderUrl + "/new_lb.aspx?" + listParameter + "%26" + cTypeParameter;

                                    RegisterEventReceiver(list);

                                    fileStream.Close();
                                    cType.Update();
                                    list.Update();

                                    #region Generate XSN
                                    //Create Main ListInfo
                                    //Main List
                                    XListInfo mListInfo = new XListInfo();
                                    mListInfo.GenerateListInfo(list);
                                    mListInfo.AddContentTypeInfo(cType);

                                    XSNOperator xsnOperator = new XSNOperator
                                    {
                                        SiteId = siteId,
                                        WebId = webId,
                                        ListId = list.ID,
                                        CTypeId = cType.Id,
                                        XSNTemplateFolder = Server.MapPath("/_layouts/ListForm2010/xsn_template/"),
                                        G_Site_Url = site.Url,
                                        G_XSN_Url =
                                            site.Url + list.RootFolder.ServerRelativeUrl + "/" +
                                            cType.ResourceFolder.Name + "/template.xsn",
                                        MListInfo = mListInfo
                                    };

                                    xsnOperator.GenerateXSN();
                                    UploadFileToFormLib(xsnOperator);
                                    #endregion
                                }
                            }
                        }
                    });
                }
                if (!string.IsNullOrEmpty(curXSNLocation))
                {
                    Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate('" + curXSNLocation + "'); }window.frameElement.commitPopup('ok');</script>");
                }
            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        private void CreateLookupForm()
        {
            string redirectUrl = SPContext.Current.Web.Url + "/_layouts/ListForm2010/LookupFormGenerator.aspx?source=" + Request["source"];
            redirectUrl += "&cType=" + ctDdl.SelectedItem.Text + "&IsDlg=1";
            Response.Redirect(redirectUrl);
        }

        private void DefaultForm()
        {
            try
            {
                string xsnLocation;
                string destFolderUrl;
                _contentTypeName = ctDdl.SelectedItem.Text;
                if (!string.IsNullOrEmpty(_contentTypeName))
                {
                    Guid siteId = SPContext.Current.Site.ID;
                    Guid webId = SPContext.Current.Web.ID;
                    Guid listId = new Guid(Request["source"]);

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                web.AllowUnsafeUpdates = true;
                                SPList list = web.Lists[listId];
                                SPContentType cType = list.ContentTypes[_contentTypeName];


                                cType.DisplayFormUrl = list.DefaultDisplayFormUrl;
                                cType.EditFormUrl = list.DefaultEditFormUrl;
                                cType.NewFormUrl = list.DefaultNewFormUrl;

                                cType.Update();
                                UnBindingEventReceiver(list);
                                list.Update();

                                if (deleteCB.Checked)
                                {
                                    //display_lb.aspx, edit_lb.aspx, new_lb.aspx
                                    destFolderUrl = web.Url + "/" + cType.ResourceFolder.Url;
                                    xsnLocation = destFolderUrl + "/template.xsn";

                                    web.GetFile(destFolderUrl + "/edit_lb.aspx").Delete();
                                    web.GetFile(destFolderUrl + "/new_lb.aspx").Delete();
                                    web.GetFile(destFolderUrl + "/display_lb.aspx").Delete();
                                    web.GetFile(xsnLocation).Delete();
                                    DeleteConfigItem(web, Convert.ToString(listId), Convert.ToString(cType.Id));
                                }
                                web.AllowUnsafeUpdates = false;
                            }
                        }
                    });
                }

                Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('ok');</script>");


            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        private void DeleteConfigItem(SPWeb web, string mListID, string mContentTypeID)
        {
            if (string.IsNullOrEmpty(mListID) || string.IsNullOrEmpty(mContentTypeID)) return;
            try
            {
                SPList configList = web.Lists[Constants.LookupForm_Config_NAME];
                SPQuery query = new SPQuery
                {
                    Query =
                        "<Where><And><Eq><FieldRef Name='Title' /><Value Type='Text'>" + mListID +
                        "</Value></Eq><Eq><FieldRef Name='mContentType' /><Value Type='Text'>" + mContentTypeID +
                        "</Value></Eq></And></Where>"
                };
                SPListItemCollection items = configList.GetItems(query);
                ArrayList deletedList = new ArrayList();
                ArrayList unbindList = new ArrayList();
                foreach (SPListItem item in items)
                {
                    string sListId = Convert.ToString(item["sTitle"]);
                    unbindList.Add(sListId);
                    deletedList.Add(item.ID);
                }
                foreach (int itemId in deletedList)
                {
                    configList.Items.DeleteItemById(itemId);
                }
                //Unbind List Event
                foreach (string sListId in deletedList)
                {
                    SPQuery unbindQuery = new SPQuery
                    {
                        Query =
                            "<Where><Eq><FieldRef Name='sTitle' /><Value Type='Text'>" + sListId +
                            "</Value></Eq></Where>"
                    };
                    SPListItemCollection sListIds = configList.GetItems(unbindQuery);
                    if (sListIds.Count == 0)
                    {
                        SPList sList = web.Lists[new Guid(sListId)];
                        UnBindingLKPEventReceiver(sList);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private Dictionary<string, string> GetViewConfigItem(SPWeb web, string mListID, string mContentTypeID)
        {
            Dictionary<string, string> views = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(mListID) && !string.IsNullOrEmpty(mContentTypeID))
            {
                try
                {
                    SPList configList = web.Lists[Constants.LookupForm_Config_NAME];
                    SPQuery query = new SPQuery
                    {
                        Query =
                            "<Where><And><Eq><FieldRef Name='Title' /><Value Type='Text'>" + mListID +
                            "</Value></Eq><Eq><FieldRef Name='mContentType' /><Value Type='Text'>" + mContentTypeID +
                            "</Value></Eq></And></Where>"
                    };
                    SPListItemCollection items = configList.GetItems(query);
                    if (items.Count > 0)
                    {
                        string dispView = Convert.ToString(items[0]["mDispView"]);
                        string dispViewReadOnly = Convert.ToString(items[0]["mDispViewReadOnly"]);
                        string editView = Convert.ToString(items[0]["mEditView"]);
                        string newView = Convert.ToString(items[0]["mNewView"]);

                        if (!string.IsNullOrEmpty(editView))
                        {
                            views.Add("DISP", dispView);
                            views.Add("DISP_ReadOnly", dispViewReadOnly);
                            views.Add("EDIT", editView);
                            views.Add("NEW", newView);
                        }

                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return views;
        }

        private void UpdateViewConfigItem()
        {
            try
            {
                _contentTypeName = ctDdl.SelectedItem.Text;
                if (!string.IsNullOrEmpty(_contentTypeName))
                {
                    Guid siteId = SPContext.Current.Site.ID;
                    Guid webId = SPContext.Current.Web.ID;
                    Guid listId = new Guid(Request["source"]);

                    SPSecurity.RunWithElevatedPrivileges(delegate
                    {
                        using (SPSite site = new SPSite(siteId))
                        {
                            using (SPWeb web = site.OpenWeb(webId))
                            {
                                web.AllowUnsafeUpdates = true;
                                SPList list = web.Lists[listId];
                                SPContentType cType = list.ContentTypes[_contentTypeName];

                                SPList configList = web.Lists[Constants.LookupForm_Config_NAME];
                                SPQuery query = new SPQuery
                                {
                                    Query =
                                        "<Where><And><Eq><FieldRef Name='Title' /><Value Type='Text'>" + listId +
                                        "</Value></Eq><Eq><FieldRef Name='mContentType' /><Value Type='Text'>" +
                                        cType.Id + "</Value></Eq></And></Where>"
                                };
                                SPListItemCollection items = configList.GetItems(query);
                                if (items.Count > 0)
                                {
                                    SPListItem item = items[0];
                                    item["mDispView"] = dispViewDdl.SelectedValue;
                                    if (dispalyFormReadOnlyCb.Checked) item["mDispViewReadOnly"] = "1";
                                    else item["mDispViewReadOnly"] = "0";
                                    item["mEditView"] = editViewDdl.SelectedValue;
                                    item["mNewView"] = newViewDdl.SelectedValue;
                                    item.Update();
                                }
                                else
                                {
                                    SPListItem item = configList.Items.Add();
                                    item["Title"] = listId;
                                    item["mContentType"] = cType.Id;
                                    item["mDispView"] = dispViewDdl.SelectedValue;
                                    if (dispalyFormReadOnlyCb.Checked) item["mDispViewReadOnly"] = "1";
                                    else item["mDispViewReadOnly"] = "0";
                                    item["mEditView"] = editViewDdl.SelectedValue;
                                    item["mNewView"] = newViewDdl.SelectedValue;
                                    item.Update();
                                }
                                web.AllowUnsafeUpdates = false;
                            }
                        }
                    });
                }

                Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('ok');</script>");


            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        #endregion

        #region GenerateXSN

        private bool IsCustomizeFormExist(SPWeb web, SPContentType ct, ref SPFile xsnFile)
        {
            string destFolderUrl = web.Url + "/" + ct.ResourceFolder.Url;
            string xsnLocation = destFolderUrl + "/template.xsn";
            if (!web.GetFile(xsnLocation).Exists) return false;
            xsnFile = web.GetFile(xsnLocation);
            return true;
        }

        private void UploadFileToFormLib(XSNOperator p_XSNOperator)
        {
            try
            {
                System.Threading.Thread.Sleep(1000);
                // SPUtility.CreateFolderUnderList(mWeb,mList.Title,"defaultInfoPath");
                string xsnPath = p_XSNOperator.SaveFolder + "\\template\\template.xsn";
                SPSite site = new SPSite(p_XSNOperator.SiteId);
                SPWeb web = site.AllWebs[p_XSNOperator.WebId];
                SPList mlist = web.Lists[p_XSNOperator.ListId];
                SPContentType mCType = mlist.ContentTypes[p_XSNOperator.CTypeId];
                SPUtility.CreateFile(site, web, mlist, mCType.ResourceFolder.Name, "template.xsn", GetXsnFileStream(xsnPath));
            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
            }
        }

        private byte[] GetXsnFileStream(string xsnPath)
        {
            byte[] buf = new byte[100];
            List<byte> bytes = new List<byte>();
            using (FileStream fs = File.Open(xsnPath, FileMode.Open, FileAccess.Read))
            {
                const int offset = 0;
                while ((fs.Read(buf, offset, buf.Length)) > 0)
                {
                    CopyOneStreamToStream(buf, bytes);
                    buf = new byte[100];
                }
            }

            return bytes.ToArray();
        }

        private void CopyOneStreamToStream(IEnumerable<byte> byte1, ICollection<byte> byte2)
        {
            foreach (byte bt in byte1)
            {
                byte2.Add(bt);
            }
        }

        #endregion

        #region RegisterEventReceiver

        private void RegisterEventReceiver(SPList list)
        {
            SPEventReceiverDefinition def1 = list.EventReceivers.Add();
            def1.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def1.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def1.Type = SPEventReceiverType.FieldAdded;
            def1.Name = "SPFieldChangeEventFieldAdded";
            def1.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def1.SequenceNumber = 1000;
            def1.Update();

            SPEventReceiverDefinition def2 = list.EventReceivers.Add();
            def2.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def2.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def2.Type = SPEventReceiverType.FieldUpdated;
            def2.Name = "SPFieldChangeEventFieldUpdated";
            def2.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def2.SequenceNumber = 1000;
            def2.Update();

            SPEventReceiverDefinition def3 = list.EventReceivers.Add();
            def3.Assembly = "ServBus.ListForm2010, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=df5827f77359eb0a";
            def3.Class = "ServBus.ListForm2010.SPFieldChangeEvent.SPFieldChangeEvent";
            def3.Type = SPEventReceiverType.FieldDeleting;
            def3.Name = "SPFieldChangeEventFieldDeleting";
            def3.Synchronization = SPEventReceiverSynchronization.Synchronous;
            def3.SequenceNumber = 1000;
            def3.Update();
        }

        private void UnBindingEventReceiver(SPList list)
        {
            List<string> eventReceiverList = new List<string>
            {
                "LKPSPFieldChangeEventFieldAdded",
                "LKPSPFieldChangeEventFieldUpdated",
                "LKPSPFieldChangeEventFieldDeleting"
            };
            for (int i = 0; i < list.EventReceivers.Count; i++)
            {
                SPEventReceiverDefinition def = list.EventReceivers[i];
                if (!eventReceiverList.Contains(def.Name)) continue;
                def.Delete();
                i--;
            }
        }

        private void UnBindingLKPEventReceiver(SPList list)
        {
            List<string> eventReceiverList = new List<string>
            {
                "LKPSPFieldChangeEventFieldAdded",
                "LKPSPFieldChangeEventFieldUpdated",
                "LKPSPFieldChangeEventFieldDeleting"
            };
            for (int i = 0; i < list.EventReceivers.Count; i++)
            {
                SPEventReceiverDefinition def = list.EventReceivers[i];
                if (!eventReceiverList.Contains(def.Name)) continue;
                def.Delete();
                i--;
            }
        }

        #endregion
    }
}
